#!/usr/bin/perl


sub string_to_hexstring {
    my $s = shift;
    my $rval = "";
    
    foreach my $i ( 0..length($s)-1 ) {
	my $v = ord(substr($s, $i, 1));
	$rval .= sprintf("%02x", $v);
    }
    
    return $rval;
}

sub fourcc_to_string {
    my $fourcc = shift;
    my $rval = "";
    
    $rval .= "\"";
    foreach my $i ( 0..3 ) {
	my $c = substr($fourcc, $i, 1);
	my $v = ord($c);
	
	if ( $v == 0 ) { $c = " "; }
	elsif ( $v < 0x20 || $v >= 0x7f ) { $c = "?"; }
	$rval .= $c;
    }
    $rval .= "\" (";
    $rval .= string_to_hexstring($fourcc);
    $rval .= ")";
    
    return $rval;
}

 ONEFILE: for (@ARGV) {
     print "----\n";
     print $_, "\n\n";
     
     open(DATA, $_) || (print("cannot be open.\n"), next ONEFILE);
     
     read(DATA, $d, 8) || die("too short file\n");
     if ( substr($d, 4) ne "ftyp" ) { (print("is not mp4 file.\n"), next ONEFILE); }
     
     $len = 0;
     $len = ord(substr($d, 0, 1)) + $len * 256;
     $len = ord(substr($d, 1, 1)) + $len * 256;
     $len = ord(substr($d, 2, 1)) + $len * 256;
     $len = ord(substr($d, 3, 1)) + $len * 256;
     
     print "length: ", $len, "\n";
     if ( $len < 16 ) { die("too short ftyp box size"); }
     if ( $len % 4 != 0 ) { die("ftyp size is not multi of 4"); }
     
     $len -= 8;
     read(DATA, $d, $len) || die("too short file");
     
     print "Major Brand:           ";
     print fourcc_to_string(substr($d, 0, 4));
     print "\n";
     
     $ver = 0;
     $ver = ord(substr($d, 4, 1)) + $ver * 256;
     $ver = ord(substr($d, 5, 1)) + $ver * 256;
     $ver = ord(substr($d, 6, 1)) + $ver * 256;
     $ver = ord(substr($d, 7, 1)) + $ver * 256;
     
     print "Major Brand Version:   ";
     print $ver;
     print " (";
     print string_to_hexstring(substr($d, 4, 4));
     print ")\n";
     
     $len -= 8;
     $d = substr($d, 8);
     $i = 0;
     while ( $len > 0 ) {
	 print "Compatible Brands [", $i, "]: ";
	 print fourcc_to_string(substr($d, 0, 4));
	 print "\n";
	 $i++;
	 $len -= 4;
	 $d = substr($d, 4);      
     }
     
     close(DATA);
 }

